package main

import (
	"bufio"
	"encoding/json"
	"io"
	"log"
	"net"
	"time"
)

type net_server struct {
	p    string
	ln   net.Listener
	conn net.Conn
}

func main() {

	var s net_server
	s.p = ":1234"
	var err error
	s.ln, err = net.Listen("tcp", s.p)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Listening")
	for {
		conn, err := s.ln.Accept()
		if err != nil {
			log.Fatal(err)
		}
		go handle_conn(conn)
	}

}

type RegisterPayload struct {
	DeviceMAC string `json:"device_mac"`
	Timestamp int64  `json:"timestamp"`
	Timezone  string `json:"timezone"`
	Cfg       struct {
		WifiSSID        string `json:"wifi_ssid"`
		WifiPass        string `json:"wifi_pass"`
		TempK           int    `json:"temp_k"`
		TempB           int    `json:"temp_b"`
		HumiK           int    `json:"humi_k"`
		HumiB           int    `json:"humi_b"`
		CollectInterval int    `json:"collect_interval"`
		UploadInterval  int    `json:"upload_interval"`
	} `json:"cfg"`
}

type RealTimeDataPayload struct {
	DeviceMAC string  `json:"device_mac"`
	Timestamp int64   `json:"timestamp"`
	Timezone  string  `json:"timezone"`
	H         float64 `json:"H"`
	T         float64 `json:"T"`
}

func processData(data map[string]interface{}, msg string) {
	typeValue, ok := data["type"].(string)
	if !ok {
		log.Println("Invalid or missing 'type' field in JSON")
		return
	}

	switch typeValue {
	case "register":
		var payload RegisterPayload
		jsonData, err := json.Marshal(data["payload"])
		if err != nil {
			log.Println("Error marshaling payload:", err)
			return
		}
		if err := json.Unmarshal(jsonData, &payload); err != nil {
			log.Println("Error unmarshaling payload:", err)
			return
		}
		log.Printf("Parsed register payload: %+v\n", payload)
	case "ack_sync_cfg":
		if _, ok := data["type"]; ok {
			log.Println("Valid ack_sync_cfg message received")
		} else {
			log.Println("Invalid ack_sync_cfg message: missing 'type' field")
		}
	case "real_time_data":
		var payload RealTimeDataPayload
		jsonData, err := json.Marshal(data["payload"])
		if err != nil {
			log.Println("Error marshaling payload:", err)
			return
		}
		if err := json.Unmarshal(jsonData, &payload); err != nil {
			log.Println("Error unmarshaling payload:", err)
			return
		}
		log.Printf("Parsed real_time_data payload: %+v\n", payload)
	default:
		log.Println("Received unknown message type:", typeValue, "data:", data)
	}
}

func handle_conn(conn net.Conn) {
	log.Println("New connection from:", conn.RemoteAddr())
	defer func() {
		log.Println("Connection closed:", conn.RemoteAddr())
		conn.Close()
	}()

	for {
		// 设置读取超时为5秒
		reader := bufio.NewReader(conn)
		if err := conn.SetReadDeadline(time.Now().Add(5 * time.Second)); err != nil {
			log.Println("Error setting read deadline:", err)
			return
		}

		msg, err := reader.ReadString('\n')
		if err != nil {
			if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
				log.Println("Read timeout:", conn.RemoteAddr())
			} else if err == io.EOF {
				log.Println("Client disconnected:", conn.RemoteAddr())
			} else {
				log.Println("Error reading from client:", err)
			}
			return
		}

		var data map[string]interface{}
		if err := json.Unmarshal([]byte(msg), &data); err != nil {
			log.Println("Error parsing JSON from client:", err)
			return
		}
		log.Printf("Client %s sent valid JSON: %+v\n", conn.RemoteAddr(), data)
		processData(data, msg)
	}

}
